# -*- coding: utf-8 -*-

from django.db import models
from django.contrib.auth.models import User

# from django.contrib.auth.models import User
# Create your models here.


ASSET_TYPE_CHOICE = (
    (str(1), u'物理机'),
    (str(2), u'虚拟机'),
    (str(3), u'容器'),
    (str(4), u'网络设备'),
    (str(5), u'安全设备'),
    (str(6), u'软件资产'),
    (str(7), u'其他资产')
)


class AssetInfo(models.Model):
    """
    所有资产信息
    """
    asset_status_choice = (
        (str(1), u'使用中'),
        (str(2), u'未使用'),
        (str(3), u'未知'),
        (str(4), u'故障'),
        (str(5), u'其他')
    )

    asset_sn = models.CharField(max_length=128, unique=True, verbose_name='资产序列号')
    asset_name = models.CharField(max_length=64, null=True, blank=True, verbose_name='资产名称')
    asset_type = models.CharField(max_length=10, choices=ASSET_TYPE_CHOICE, default='1', verbose_name='资产类型')

    vendor = models.ForeignKey('Vendor', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='制造商')
    status = models.CharField(max_length=10, choices=asset_status_choice, default='3', verbose_name='设备状态')
    idc = models.ForeignKey('Idc', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='所在机房')
    admin = models.ForeignKey(User, null=True, blank=True, related_name='admin', verbose_name='资产管理员',
                              on_delete=models.SET_NULL)
    manage_ip = models.GenericIPAddressField(protocol='both', null=True, blank=True, verbose_name='管理IP')
    contract = models.ForeignKey('Contract', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='合同')
    purchase_date = models.DateField(null=True, blank=True, verbose_name="购买日期")
    pass_date = models.DateField(null=True, blank=True, verbose_name="过保日期")
    price = models.FloatField(null=True, blank=True, verbose_name="价格")
    approved_by = models.ForeignKey(User, null=True, blank=True, related_name='approved_by', verbose_name='批准人',
                                    on_delete=models.SET_NULL)
    c_time = models.DateTimeField(auto_now_add=True, verbose_name='批准日期')
    u_time = models.DateTimeField(auto_now=True, verbose_name='更新日期')
    tags = models.ManyToManyField('Tag', null=True, blank=True, verbose_name='标签')

    remarks = models.TextField(null=True, blank=True, verbose_name='备注信息')

    def __str__(self):
        return '<sn: {sn}> - <name: {name}> - <type: {type}>'.format(
            sn=self.asset_sn,
            name=self.asset_name,
            type=self.get_asset_type_display()
        )

    class Meta:
        db_table = 'tb_AssetInfo'
        verbose_name = '资产信息'
        verbose_name_plural = verbose_name


class ServerInfo(models.Model):
    """
    服务器信息
    """
    server_type_choice = (
        (str(1), u'PC电脑'),
        (str(2), u'塔式服务器'),
        (str(3), u'机架式服务器'),
        (str(4), u'刀片服务器'),
    )

    created_by_choice = (
        (str(1), u'脚本录入'),
        (str(2), u'手工录入'),
    )

    asset = models.OneToOneField('AssetInfo', on_delete=models.CASCADE)  # 一对一关联，级联删除
    hostname = models.CharField(max_length=50, unique=True, verbose_name='主机名')
    ser_type = models.CharField(max_length=10, choices=server_type_choice, default='3', verbose_name='服务器类型')
    created_by = models.CharField(max_length=10, choices=created_by_choice, default='1', verbose_name='添加方式')
    hosted_on = models.ForeignKey('self', related_name='hosted_on_server', null=True, blank=True, verbose_name='宿主机',
                                  on_delete=models.CASCADE)  # 虚拟机容器专用字段
    # CPU信息
    cpu_mode = models.CharField(max_length=128, null=True, blank=True, verbose_name='CPU型号')
    cpu_count = models.CharField(max_length=128, null=True, blank=True, verbose_name='CPU个数')
    cpu_core_count = models.CharField(max_length=128, null=True, blank=True, verbose_name='CPU内核数')
    # 内存
    total_memory = models.CharField(max_length=64, null=True, blank=True, verbose_name='总内存大小')
    # 硬盘
    disk_info = models.CharField(max_length=255, null=True, blank=True, verbose_name='硬盘信息')
    raid_type = models.CharField(max_length=128, null=True, blank=True, verbose_name='RAID类型')
    # 网卡
    nic_name = models.CharField(max_length=64, null=True, blank=True, verbose_name='网卡名称')
    nic_IPv4 = models.CharField(max_length=64, null=True, blank=True, verbose_name='IPv4地址')
    nic_IPv6 = models.CharField(max_length=200, null=True, blank=True, verbose_name='IPv6地址')
    nic_mac = models.CharField(max_length=64, null=True, blank=True, verbose_name='MAC地址')
    nic_mask = models.CharField(max_length=64, null=True, blank=True, verbose_name='子网掩码')

    ser_model = models.CharField(max_length=128, null=True, blank=True, verbose_name='服务器型号')
    os_type = models.CharField(max_length=64, null=True, blank=True, verbose_name='系统类型')
    os_release = models.CharField(max_length=64, null=True, blank=True, verbose_name='系统版本')
    os_distribution = models.CharField(max_length=64, null=True, blank=True, verbose_name='发行商')

    remarks = models.TextField(null=True, blank=True, verbose_name='备注信息')

    def __str__(self):
        return '<sn: {sn}> - <name: {name}> - <type: {type}> - <model: {model}>'.format(
            sn=self.asset.asset_sn,
            name=self.asset.asset_name,
            type=self.get_ser_type_display(),
            model=self.ser_model
        )

    class Meta:
        db_table = 'tb_ServerInfo'
        verbose_name = '服务器信息'
        verbose_name_plural = verbose_name


class NetworkDev(models.Model):
    """
    安全/网络设备
    """
    net_dev_choice = (
        (str(1), '交换机'),
        (str(2), '路由器'),
        (str(3), '防火墙'),
        (str(4), 'VPN设备'),
        (str(5), '网关'),
        (str(6), '负载均衡'),
    )
    asset = models.OneToOneField('AssetInfo', on_delete=models.CASCADE)  # 一对一关联，级联删除
    dev_type = models.CharField(max_length=10, choices=net_dev_choice, default='1', verbose_name='设备类型')
    vlan_ip = models.CharField(max_length=128, null=True, blank=True, verbose_name='VlanIp')
    intranet_ip = models.CharField(max_length=128, null=True, blank=True, verbose_name='内网IP')
    dev_model = models.CharField(max_length=128, default='未知型号', verbose_name='设备型号')
    firmware = models.CharField(max_length=128, null=True, blank=True, verbose_name='固件版本')
    port_num = models.SmallIntegerField(null=True, blank=True, verbose_name='端口个数')
    dev_detail = models.TextField(null=True, blank=True, verbose_name='详细配置')

    remarks = models.TextField(null=True, blank=True, verbose_name='备注信息')

    def __str__(self):
        return '<sn: {sn}> - <name: {name}> - <type: {type}> - <model: {model}>'.format(
            sn=self.asset.asset_sn,
            name=self.asset.asset_name,
            type=self.get_dev_type_display(),
            model=self.dev_model
        )

    class Meta:
        db_table = 'tb_NetworkDev'
        verbose_name = '安全/网络设备'
        verbose_name_plural = verbose_name


class Software(models.Model):
    """
    软件资产
    只保存付费购买的软件
    """
    software_type_choice = (
        (str(1), '操作系统'),
        (str(2), '办公软件'),
        (str(3), '开发软件'),
        (str(4), '业务软件')
    )
    asset = models.OneToOneField('AssetInfo', on_delete=models.CASCADE)  # 一对一关联，级联删除
    soft_type = models.CharField(max_length=10, choices=software_type_choice, default='2', verbose_name='软件类型')
    license_num = models.IntegerField(default=1, verbose_name="授权数量")
    version = models.CharField(max_length=64, unique=True, help_text='例如: RedHat release 7 (Final)',
                               verbose_name='软件/系统版本')

    # def __str__(self):
    #     return '%s---%s' % (self.get_software_type_display(), self.version)
    def __str__(self):
        return '<sn: {sn}> - <name: {name}> - <type: {type}> - <version: {version}>'.format(
            sn=self.asset.asset_sn,
            name=self.asset.asset_name,
            type=self.get_soft_type_display(),
            version=self.version
        )

    class Meta:
        db_table = 'tb_Software'
        verbose_name = '数据中心'
        verbose_name_plural = verbose_name


class Idc(models.Model):
    """
    数据中心
    """
    idc_name = models.CharField(max_length=200, unique=True, verbose_name='机房名称')
    idc_addr = models.CharField(max_length=200, null=True, blank=True, verbose_name='机房地址')
    idc_tel = models.CharField(max_length=30, null=True, blank=True, verbose_name='机房电话')
    cabinet = models.CharField(max_length=100, null=True, blank=True, verbose_name='机柜信息')

    remarks = models.TextField(null=True, blank=True, verbose_name='备注信息')

    def __str__(self):
        return '<name: {name}> - <tel: {tel}>'.format(
            name=self.idc_name,
            tel=self.idc_tel,
        )

    class Meta:
        db_table = 'tb_IDC'
        verbose_name = '数据中心'
        verbose_name_plural = verbose_name


class Vendor(models.Model):
    """
    制造商/厂商
    """
    ven_name = models.CharField(max_length=64, unique=True, verbose_name='制造商')
    ven_tel = models.CharField(max_length=30, null=True, blank=True, verbose_name='电话号码')

    remarks = models.TextField(null=True, blank=True, verbose_name='备注信息')

    def __str__(self):
        return '<name: {name}> - <tel: {tel}>'.format(
            name=self.ven_name,
            tel=self.ven_tel
        )

    class Meta:
        db_table = 'tb_Vendor'
        verbose_name = '制造商'
        verbose_name_plural = verbose_name


class Contract(models.Model):
    """
    合同
    """
    con_sn = models.CharField(max_length=128, unique=True, verbose_name='合同号')
    con_name = models.CharField(max_length=64, verbose_name="合同名")
    con_price = models.IntegerField(verbose_name='合同金额')
    con_detail = models.TextField(null=True, blank=True, verbose_name='合同详情')
    electronic_copy = models.FileField(upload_to='contract/', max_length=250, null=True, blank=True,
                                       verbose_name='合同电子副本')
    license_num = models.IntegerField(null=True, blank=True, verbose_name='license数量')
    s_time = models.DateField(null=True, blank=True, verbose_name='开始日期')
    e_time = models.DateField(null=True, blank=True, verbose_name='失效日期')
    c_time = models.DateField(auto_now_add=True, verbose_name='创建日期')
    u_time = models.DateField(auto_now=True, verbose_name='修改日期')

    remarks = models.TextField(null=True, blank=True, verbose_name='备注信息')

    def __str__(self):
        return '<sn: {sn}> - <name: {name}>'.format(
            sn=self.con_sn,
            name=self.con_name,
        )

    class Meta:
        db_table = 'tb_Contract'
        verbose_name = '合同信息'
        verbose_name_plural = verbose_name


class Tag(models.Model):
    """
    标签
    """
    tag_name = models.CharField(max_length=64, unique=True, verbose_name='标签名')
    c_time = models.DateField(auto_now_add=True, verbose_name='创建日期')

    remarks = models.TextField(null=True, blank=True, verbose_name='备注信息')

    def __str__(self):
        return self.tag_name

    class Meta:
        db_table = 'tb_Tag'
        verbose_name = '标签信息'
        verbose_name_plural = verbose_name


class NewAssetApprovalZone(models.Model):
    """
    新资产待审批区
    """
    new_sn = models.CharField(max_length=128, unique=True, verbose_name='新资产序列号')
    new_name = models.CharField(max_length=64, null=True, blank=True, verbose_name='新资产名称')
    new_type = models.CharField(max_length=10, choices=ASSET_TYPE_CHOICE, default='1', verbose_name='新资产类型')

    Vendor = models.CharField(max_length=64, null=True, blank=True, verbose_name='生产厂商')
    new_model = models.CharField(max_length=64, null=True, blank=True, verbose_name='新资产型号')

    cpu_mode = models.CharField(max_length=128, null=True, blank=True, verbose_name='CPU型号')
    cpu_count = models.CharField(max_length=64, null=True, blank=True, verbose_name='CPU个数')
    cpu_core_count = models.CharField(max_length=64, null=True, blank=True, verbose_name='CPU内核数')
    total_memory = models.CharField(max_length=64, null=True, blank=True, verbose_name='总内存大小')
    disk_info = models.CharField(max_length=255, null=True, blank=True, verbose_name='硬盘大小')
    data = models.TextField(verbose_name='资产详细数据')
    c_time = models.DateTimeField(auto_now_add=True, verbose_name='汇报日期')
    u_time = models.DateTimeField(auto_now=True, verbose_name='数据更新日期')
    approved = models.BooleanField(default=False, verbose_name='是否批准')

    remarks = models.TextField(null=True, blank=True, verbose_name='备注信息')

    def __str__(self):
        return '<sn: {sn}> - <name: {name}> - <type: {type}> - <model: {model}>'.format(
            sn=self.new_sn,
            name=self.new_name,
            type=self.get_new_type_display(),
            model=self.new_model
        )

    class Meta:
        db_table = 'tb_NewAssetApprovalZone'
        verbose_name = '新资产待审批区'
        verbose_name_plural = verbose_name


class EventLog(models.Model):
    """
    日志
    在关联对象被删除的时候，不能一并删除，需保留日志
    """

    event_type_choice = (
        (str(1), '硬件更换'),
        (str(2), '新增配件'),
        (str(3), '设备下线'),
        (str(4), '设备上线'),
        (str(5), '定期维护'),
        (str(6), '其它'),
    )

    event_name = models.CharField(max_length=200, verbose_name='事件名称')
    asset = models.ForeignKey('AssetInfo', null=True, blank=True, on_delete=models.SET_NULL)  # 当资产审批成功时有这项数据
    new_asset = models.ForeignKey('NewAssetApprovalZone', null=True, blank=True, on_delete=models.SET_NULL)
    event_type = models.CharField(max_length=10, choices=event_type_choice, default='4', verbose_name='事件类型')
    component = models.CharField(max_length=250, null=True, blank=True, verbose_name='事件子项')
    event_detail = models.TextField(null=True, blank=True, verbose_name='事件详情')
    event_date = models.DateTimeField(auto_now_add=True, verbose_name='事件时间')
    executor = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='事件执行人')

    remarks = models.TextField(null=True, blank=True, verbose_name='备注信息')

    def __str__(self):
        return '<id: {id}> - <event_name: {event_name}> - <type: {type}> - <executor: {executor}>'.format(
            id=self.id,
            event_name=self.event_name,
            type=self.get_event_type_display(),
            executor=self.executor
        )

    class Meta:
        db_table = 'tb_EventLog'
        verbose_name = '事件记录'
        verbose_name_plural = verbose_name
